package cgl.granules.exchange;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import cgl.granules.exception.MarshallingException;
import cgl.granules.scheduler.ResourceMetrics;
import cgl.granules.util.MarshallingUtil;

/**
 * This class encapsulates exchanges related the discovery of resources. This
 * class could also be used for reservation of resources.
 * 
 * @author Shrideep Pallickara
 * 
 */
public class ResourceDiscovery extends Exchange {
	private int resourceType;
	private ResourceMetrics resourceMetrics;

	protected ResourceDiscovery() {
	}

	protected ResourceDiscovery(int resourceType, String respondTo) {
		this.resourceType = resourceType;
		setExchangeType(ExchangeType.RESOURCE_DISCOVERY);
		setRespondTo(respondTo);
		setRequest();
	}

	protected ResourceDiscovery(int conditionFlag, String description,
			ResourceMetrics resourceMetrics, String respondTo) {
		this.resourceMetrics = resourceMetrics;
		setRespondTo(respondTo);
		setExchangeType(ExchangeType.RESOURCE_DISCOVERY);
		setResponse();

		setDescription(description);
		setConditionFlag(conditionFlag);
	}

	/**
	 * @return the resourceType
	 */
	public int getResourceType() {
		return resourceType;
	}

	/**
	 * @return the resourceMetrics
	 */
	public ResourceMetrics getResourceMetrics() {
		return resourceMetrics;
	}

	@Override
	public boolean isValidExchangeSubType() {
		return true;
	}

	@Override
	public byte[] marshallExchangeSpecificElements() throws IOException,
			MarshallingException {
		byte[] marshalledBytes = null;
		ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
		DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(
				baOutputStream));

		if (isRequest()) {
			dout.writeInt(resourceType);
		}

		if (isResponse()) {
			if (resourceMetrics != null) {
				byte[] resourceMetricBytes = resourceMetrics.getBytes();
				dout.writeInt(resourceMetricBytes.length);
				dout.write(resourceMetricBytes);
			}
		}

		/** check to see if this is a request or response and do accordingly */
		dout.flush();
		marshalledBytes = baOutputStream.toByteArray();
		return marshalledBytes;
	}

	@Override
	public void unmarshallExchangeSpecificElements(byte[] exchangeSpecificBytes)
			throws IOException, MarshallingException {
		ByteArrayInputStream baInputStream = new ByteArrayInputStream(
				exchangeSpecificBytes);
		DataInputStream din = new DataInputStream(new BufferedInputStream(
				baInputStream));
		MarshallingUtil marshaller = MarshallingUtil.getInstance();

		if (isRequest()) {
			resourceType = din.readInt();
		}

		if (isResponse()) {
			byte[] resourceMetricBytes = new byte[din.readInt()];
			din.readFully(resourceMetricBytes);
			resourceMetrics = new ResourceMetrics(resourceMetricBytes);
		}

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
